import { ref, reactive, nextTick, shallowRef } from 'vue'
import { ImagePreview } from 'vant'
import {
  isAndroid,
  jumpHttp,
  isIos,
  isMobile,
  isWx,
  isWeixinMini
} from '../utils/host'
import { addTokenToUrl, removeImageTags } from '../utils/token'
import { fetchEventSource } from '@microsoft/fetch-event-source'
import qs from 'qs'
import debounce from 'lodash/debounce'
import { getTransportStatus, newEvaluate } from '../service/api'
import scrollTop from '../utils/scrollTop'

const barStyle = {
  type: 'bar',
  barWidth: '16',
  label: {
    show: true, // 显示标签
    position: 'top'
  }
}
const lineStyle = {
  type: 'line',
  boundaryGap: false,
  // name: '高数',
  label: {
    show: true
  },
  symbol: 'circle', // 数据点为实心圆
  lineStyle: {
    type: 'solid',
    color: '#76B2FF'
  },
  itemStyle: {
    color: '#4690FF ', // 数据点颜色
    borderColor: '#76B2FF',
    borderWidth: 2 // 数据点边框宽度
  },
  symbolSize: 6, // 数据点大小
  areaStyle: {
    // 使用渐变色
    normal: {
      color: {
        type: 'linear',
        x: 0,
        y: 0,
        x2: 0,
        y2: 1,
        colorStops: [
          { offset: 0, color: '#B5D4FF' }, // 渐变起始颜色
          { offset: 1, color: 'rgba(84,153,248,0)' } // 渐变结束颜色
        ],
        global: false // 缺省为 false
      }
    }
  }
}

const toObjectURL = (byteString) => {
  const arrayBuffer = hexStringToByteArray(byteString)
  const mp3Blob = new Blob([arrayBuffer], { type: 'audio/mpeg' })
  const src = URL.createObjectURL(mp3Blob)
  return src
}
// 16进制转字节数组
const hexStringToByteArray = (hexString) => {
  const byteArray = []
  for (let i = 0; i < hexString.length; i += 2) {
    byteArray.push(parseInt(hexString.substring(i, i + 2), 16))
  }
  return new Uint8Array(byteArray)
}

export const useCommonCheckbox = (
  proxy,
  sessionId,
  playVoiceAndAnimate,
  stopVoiceAndAnimate,
  Emit,
  animateScale,
  model,
  dialogSettings,
  defaultFeedType
) => {
  const isZDWX = ref()
  let listIds = [] // 推荐应用的ids
  const config = proxy.$config
  const chatBox = ref() // 聊天框ref
  const autoScroll = ref(true) // 是否自动滚动到页面最底部，触发touchstart 取消自动滚动
  const messages = ref([]) // 消息列表
  const isAnswering = ref(false) // 是否在回答问题
  const isPending = ref(false) // 问题发送之后，出答案之前
  const docObj = ref({
    id: null,
    name: ''
  }) // 制度问询 文档id
  const processObj = ref({
    jtype: null,
    link: '',
    appendToken: 0
  }) // 跳转事务对象
  // 检测前置异常
  const testTransportStatus = () => {
    getTransportStatus().then((res) => {
      if (res.transportStatus === 1) {
        pushPreAbnormalMessage(res.transportErrorMsg)
      }
    })
  }

  // 控制智能助手需要的消息
  let smartMessages = []

  // 富文本转成文本，去掉html标签
  const getSimpleText = (html) => {
    const re1 = new RegExp('<.+?>', 'g') // 匹配html标签的正则表达式，"g"是搜索匹配多个符合的内容
    const arrEntities = {
      lt: '<',
      gt: '>',
      nbsp: ' ',
      amp: '&',
      quot: '"',
      ldquo: '“',
      mdash: '—',
      rdquo: '”'
    }
    return html
      .replace(re1, '')
      .replace(
        /&(lt|gt|nbsp|amp|quot|ldquo|mdash|rdquo);/gi,
        function (all, t) {
          return arrEntities[t]
        }
      )
  }

  // 发送问题
  const send = (askObj) => {
    if (isPending.value || isAnswering.value) {
      return
    }
    // 发送问题停止语音播放
    if (!isIos()) {
      if (Emit) {
        Emit('playVoice', '')
      }
    }
    if (controller) {
      controller.abort()
    }
    stopVoiceAndAnimate()
    if (askObj.type !== 3) {
      // type:3 上传图片
      messages.value.push({
        type: 'User',
        message: getSimpleText(askObj.data.name),
        isLoading: false
      })
      smartMessages.push({
        type: 'User',
        message: getSimpleText(askObj.data.name),
        isLoading: false
      })
    }
    newGetAnswer(askObj)

    animateScale()
  }

  // 发送input框的问题
  const sendInput = (val) => {
    if (val) {
      send({
        data: {
          name: val
        }
      })
    }
  }

  // 滚到底部
  const scroll = () => {
    if (chatBox.value && autoScroll.value) {
      nextTick(() => {
        scrollTop(chatBox.value, 20)
      })
    }
  }

  // 是否显示客服
  const continueNoanswerTimes = ref(0) // 连续没有答案的次数，第三次需要显示 人工客服跳转链接
  const checkShowKefu = () => {
    if (!config.manServiceUrl) {
      // 没有配置人工客服地址
    } else {
      setTimeout(() => {
        messages.value.push({
          message: '',
          type: 'Kefu',
          isLoading: false
        })
        scroll()
      }, 200)
    }
  }

  // 前置异常消息
  const pushPreAbnormalMessage = (
    message = '检测到您所在的学校前置异常，已帮您通知，工程师正快马加鞭为您解决中~请耐心等待服务恢复。'
  ) => {
    messages.value.push({
      type: 'PreAbnormal',
      message,
      isLoading: false
    })
  }

  // agnet消息
  const pushAgent = (type) => {
    isZDWX.value = false
    autoScroll.value = true
    const lastMessage = messages.value[messages.value.length - 1]
    if (lastMessage && type === lastMessage.type) return
    // type "ZNT": 智能体
    let typeName = ''
    switch (type) {
      case 'ZNT':
        typeName = ''
        break
      default:
        typeName = ''
    }
    if (typeName) {
      messages.value.push({
        type: 'Stitle',
        showInfo: true,
        isHistory: true,
        isTextEnd: true,
        message: `欢迎使用${typeName}服务`
      })
    }
    messages.value.push({
      type,
      isLoading: false
    })
    scroll()
  }

  // 新版获取答案
  let controller = null
  let voiceBuffer = '' // 语音16进制  用于实时语音流播放 安卓
  let voiceBufferEnd = true // 接口的语音流是否结束
  let voiceAllStream = '' // 获取到的语音流叠加  用于ios端 不只支持 实时语音流播放 全部获取二进制语音或者主动中端消息之后 转成 ObjectURL 点击播放
  const newGetAnswer = (askObj) => {
    autoScroll.value = true
    isPending.value = true
    // 发起新问题，清空之前的应用ids
    listIds = []
    const answerR = reactive({
      name: askObj.data.name,
      type: 'Bot', // 消息类型
      isLoading: true, // 加载中，收到接口消息 就变成 false
      answer: '', // 原始答案
      message: '', // 用于页面显示（处理过的答案）
      uuid: '', // 消息唯一标识
      thinking: '', // deepseek思考
      thinkFinished: false, // deepseek思考完成
      isTextEnd: false, // 接口返回文字流是否结束
      stype: null, // 消息类型，
      isActive: true, // 当前正在处理的消息
      showInfo: false, // 播放完毕显示其他信息
      needUploadImg: false, // 需要上传图片
      list: [], // 推荐功能列表 点击跳转
      source: [], // 网络搜索来源
      quote: [], // faq来源
      extraData: {
        type: '',
        showDownload: false,
        data: {}
      }, // 图标
      description: '', // 数据说明
      processInfo: '', // 问数进度信息
      btns: [], // 按钮 返回答案里面有按钮，点击按钮，发送按钮对应的文本 继续对话
      opsStatus: '0', // 点赞点踩状态
      hrefList: [], // type =7 返回的 跳转链接数组
      chatType: '', // 回答接口返回的，用于点赞点踩
      src: '', // 音频文件地址
      isError: false, // 是否是系统异常的答案
      actionType: 'normal' // normal  welcome  byebye
    })
    messages.value.forEach((item) => {
      item.isActive = false
    })
    messages.value.push(answerR)
    smartMessages.push(answerR)
    scroll()
    let BASEURL = ''
    if (import.meta.env.MODE.trim() === 'development') {
      BASEURL = '/apis/virtualhuman'
    } else {
      BASEURL = '/virtualhuman2'
    }

    const options = {
      isFirstBuffer: true, // 是否是第一个音频流
      isFirstUsefulBuffer: true // 是否是第一个可以播放的组合音频流
    }

    controller = new AbortController()
    const signal = controller.signal
    // 主动中端流
    signal.addEventListener('abort', () => {
      isAnswering.value = false
      isPending.value = false
      answerR.isTextEnd = true
      answerR.showInfo = true
      answerR.isLoading = false
      answerR.message = window.md
        .render(answerR.answer)
        .replaceAll('&lt;br&gt;', '<br />')
      clearInterval(options.textTimer)
      clearInterval(options.speechTimer)
      voiceBuffer = ''
      if (!isIos()) {
        window.player.stop()
      }
      if (isIos()) {
        answerR.src = voiceAllStream ? toObjectURL(voiceAllStream) : ''
      }
      scroll()
    })

    voiceAllStream = ''
    resetProcess()

    const qData = {
      ask: askObj.data.name,
      sessionId: sessionId.value || config.sessionId,
      model: config.showBigModelList == 1 ? model.value : 'qwen-plus', // 不显示大模型切换button，默认使用qwen-plus
      timestamp: new Date().getTime(),
      ...dialogSettings
    }

    if (docObj.value.id) {
      qData.docId = docObj.value.id
      qData.docName = docObj.value.name
    }

    if (isZDWX.value) {
      qData.type = 'zdwx'
    }

    fetchEventSource(`${BASEURL}/serverApi/question/streamAnswer`, {
      method: 'POST',
      headers: {
        'Blade-Auth': 'bearer ' + window.access_token,
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      signal,
      openWhenHidden: true,
      body: qs.stringify(qData),
      onmessage(res) {
        isPending.value = false
        const ret = JSON.parse(res.data)
        if (ret.code === 200) {
          const data = ret.data
          if (data.finish !== 1 && data.type !== 11) {
            isAnswering.value = true
          }
          if (data.chatType && data.finish !== 1 && data.finish !== 11) {
            answerR.chatType = data.chatType
          }
          // deepseek思考
          if (data.thinking) {
            answerR.thinking = answerR.thinking + data.thinking
            window.md.render(answerR.thinking)
            scroll()
          }
          continueNoanswerTimes.value = 0
          newExecAnswer(answerR, data, options)
        } else {
          executeErrorMessage(answerR)
        }
      },
      onerror(err) {
        executeErrorMessage(answerR)
        throw err
      }
    })
  }
  const newExecAnswer = (answerObj, data, options) => {
    // data.tr = [[1, 2, 3]]
    // data.th = [1, 2, 4]
    // data.list = [{
    //   name: '测试',
    //   link: 'http://baidu.com',
    //   appendToken: 1,
    //   icon: 'https://wmxytest.oss-cn-hangzhou.aliyuncs.com/upload/20231113/6d9bb54f9e0a9ad13bce27f5e491b451.png'
    // }]
    // data.btns = ['111', '333333']
    if (data.list) {
      data.list.forEach((item) => {
        if (listIds.indexOf(item.id) === -1) {
          listIds.push(item.id)
          answerObj.list.push(item)
        }
      })
    }
    if (data.recommendList) {
      data.recommendList.forEach((item) => {
        if (listIds.indexOf(item.id) === -1) {
          listIds.push(item.id)
          answerObj.list.push(item)
        }
      })
    }
    if (data.btns) {
      answerObj.btns = data.btns
    }
    // 其他表格数据
    if (data?.tr) {
      answerObj.extraData.type = 'table'
      answerObj.extraData.data.th = data?.th || []
      answerObj.extraData.data.tr = data?.tr || []
    }
    // 问数type类型为8
    let shardingInformation = {}
    if (data?.type == 8) {
      if (data.shardingInformation) {
        shardingInformation = JSON.parse(data.shardingInformation)
      }
      // 数据说明
      answerObj.description = data.answerInformation
        ? data.answerInformation
        : ''
      // 问数进度
      answerObj.processInfo = data.processInfo ? data.processInfo : ''
    }
    // 纯文本
    if (data?.chartType == 0) {
      answerObj.extraData.type = 'text'
      answerObj.extraData.data.text = shardingInformation || ''
    }

    // chartType（0文字，1表格，2折线图，3柱状图，4饼图）
    // shardingInformation = {
    //   columns: ['交易日期', '交易地点', '交易金额', '交易类型', '卡内余额', '流水号12312313123', '交易日期1', '交易地点1', '交易金额1', '交易类型1', '卡内余额1', '流水号1'],
    //   index: [0],
    //   data: [[66, 80, 5, 55, 33, 66, 66, 80, 5, 55, 33, 66]]
    // }
    // data.chartType = 4
    //  问数表格数据
    if (data.chartType == 1) {
      answerObj.extraData.type = 'table'
      const columns = shardingInformation?.columns || []
      const _data = shardingInformation?.data || []
      answerObj.extraData.data.th = columns.length > 0 ? columns : []
      answerObj.extraData.data.tr = _data.length > 0 ? _data : []
      answerObj.extraData.showDownload = _data.length > 0
    }
    if (data.chartType == 3) {
      answerObj.extraData.type = 'bar'
      const columns = shardingInformation?.columns || []
      const _data =
        shardingInformation?.data?.length > 0 ? shardingInformation?.data : []
      answerObj.extraData.data.xAxis = columns.length > 0 ? columns : []
      answerObj.extraData.data.series = []
      _data.forEach((item) => {
        const obj = {
          data: item,
          ...barStyle
        }
        answerObj.extraData.data.series.push(obj)
      })
      answerObj.extraData.showDownload = _data.length > 0
    }
    if (data.chartType == 2) {
      answerObj.extraData.type = 'line'
      const columns = shardingInformation?.columns || []
      const _data =
        shardingInformation?.data?.length > 0 ? shardingInformation?.data : []
      answerObj.extraData.data.xAxis = columns.length > 0 ? columns : []
      answerObj.extraData.data.series = []
      _data.forEach((item) => {
        const obj = {
          data: item,
          ...lineStyle
        }
        answerObj.extraData.data.series.push(obj)
      })
      answerObj.extraData.showDownload = _data.length > 0
    }
    if (data.chartType == 4) {
      answerObj.extraData.type = 'pie'
      const columns = shardingInformation?.columns || []
      const _data =
        shardingInformation?.data?.length > 0
          ? shardingInformation?.data[0]
          : []
      const series = []
      if (columns && _data) {
        columns.map((item, index) => {
          series.push({
            value: _data[index],
            name: item
          })
        })
        answerObj.extraData.data.series = series
      }
      answerObj.extraData.showDownload = _data.length > 0
    }
    // 三方业务预处理，后端暂时未实现
    if (data.dComponent) {
      answerObj.dComponent = shallowRef(window.AiComponent.PayChoosePaymentList)
    }
    if (data.finish === 1) {
      autoScroll.value = true
      isAnswering.value = false
      answerObj.isLoading = false
      if (data.type !== 11) {
        answerObj.isTextEnd = true
        setTimeout(() => {
          answerObj.showInfo = true
          scroll()
        }, 50)
        // 自动跳转
        if (isIos()) {
          setTimeout(() => {
            jumpByProcessID()
          }, 1000)
        }
        if (!isIos() && processObj.value.link) {
          setTimeout(() => {
            jumpByProcessID()
          }, 1000)
        }
      }
      // 结束标识
      if (data.type === 11) {
        voiceBufferEnd = true
        // 语音结束
        if (!isIos() && voiceBuffer) {
          // 修复语音播放不完整的问题（最后一小段没播放）
          const ab = hexStringToByteArray(voiceBuffer)
          window.player.receiveAudioData(ab)
          voiceBuffer = ''
        }
        if (isIos()) {
          isAnswering.value = false
          answerObj.src = voiceAllStream ? toObjectURL(voiceAllStream) : ''
        }
      }
    } else if (data.type === 11) {
      voiceAllStream = voiceAllStream + data.content
      if (!isIos()) {
        if (options.isFirstBuffer) {
          voiceBufferEnd = false
          // 控制语音播放的定时器
          options.speechTimer = setInterval(() => {
            const delta =
              window.player.sourceBuffer.timestampOffset -
              window.player.audio.currentTime
            if (voiceBufferEnd) {
              if (delta < 0.4) {
                clearInterval(options.speechTimer)
                window.player.cb()
              }
            }
          }, 500)
        }
        voiceBuffer = voiceBuffer + data.content
        if (voiceBuffer.length > 15000) {
          const ab = hexStringToByteArray(voiceBuffer)
          window.player.receiveAudioData(ab)
          voiceBuffer = ''
          if (options.isFirstUsefulBuffer) {
            playVoiceAndAnimate('OneAnswer')
            options.isFirstUsefulBuffer = false
          }
        }
        options.isFirstBuffer = false
      }
    } else if (data.type === 1) {
      // 大模型返回
      answerObj.stype = 1
      answerObj.isLoading = false
    } else if (data.type === 2) {
      // 普通业务办理
      answerObj.stype = 2
      isAnswering.value = false // 没有语音
      answerObj.isLoading = false
    } else if (data.type === 3) {
      // 跳转业务办理
      answerObj.stype = 3
      answerObj.isLoading = false
      let appList = []
      if (data.subappConfigList && data.subappConfigList.length > 0) {
        appList = data.subappConfigList.map((item) => {
          return {
            ...item,
            jtype: item.type,
            link: !isMobile() ? item.pcLink : item.link,
            appendToken: item.appendToken,
            putTokenName: item.putTokenName || 'token',
            gainTokenName: item.gainTokenName || 'token',
            id: item.id || '',
            name: item.name || '',
            icon: item.icon || ''
          }
        })
        // interactionMode，1是列表，2是跳转
        if (config.interactionMode == '2') {
          processObj.value.jtype = appList[0].type
          processObj.value.link = appList[0].link
          processObj.value.appendToken = appList[0].appendToken
          processObj.value.putTokenName = appList[0].putTokenName || 'token'
          processObj.value.gainTokenName = appList[0].gainTokenName || 'token'
        } else {
          answerObj.list = appList
        }
      }
    } else if (data.type === 4) {
      // 返回带有文档来源
      answerObj.stype = 4
      if (data.shardingInformation) {
        answerObj.quote = data.shardingInformation
      }
    } else if (data.type === 5) {
      // faq
      answerObj.stype = 5
      if (data.actionType === 'welcome') {
        answerObj.actionType = 'welcome'
      } else if (data.actionType === 'byebye') {
        answerObj.actionType = 'byebye'
      }
      // 屏蔽来源
      answerObj.quote = []
      answerObj.isLoading = false
      // if (data.shardingInformation) {
      //   answerObj.quote = data.shardingInformation
      // }
    } else if (data.type === 6) {
      // 表格
      answerObj.stype = 6
      isAnswering.value = false // 没有语音
      answerObj.isLoading = false
    } else if (data.type === 7) {
      // 返回的content内容是 可点击跳转的链接(集团客服 钉钉知识库 需求)
      answerObj.stype = 7
      if (data.shardingInformation) {
        answerObj.hrefList = data.shardingInformation
      }
      answerObj.isLoading = false
    } else if (data.type === 8) {
      // 问数类型自动滚动
      if (!answerObj.stype) {
        setTimeout(() => {
          scroll()
        }, 30)
      }
      // 智能问数
      answerObj.stype = 8
      answerObj.isLoading = false
    } else if (data.type === 12) {
      // 联网搜索答案
      answerObj.stype = 12
    } else if (data.type === 13) {
      answerObj.stype = 4
      // 知识库来源
      if (data.shardingInformation) {
        answerObj.quote = data.shardingInformation
      }
    } else if (data.type === 14) {
      answerObj.stype = 12
      // 联网搜索来源
      if (data.shardingInformation) {
        answerObj.source = data.shardingInformation
      }
    } else if (data.type === 21) {
      // 需要上传图片
      answerObj.stype = 21
      answerObj.needUploadImg = true
      isAnswering.value = false // 没有语音
      answerObj.isLoading = false
    } else if (data.type === 22) {
      // 按钮
      answerObj.stype = 22
      answerObj.isLoading = false
    } else if (data.type === 31) {
      // 智能助手业务
      answerObj.stype = 31
      answerObj.isTextEnd = true
      answerObj.isLoading = false

      // 通知客户端与大模型建立socket链接
      const lastMessages = smartMessages.slice(-6)
      // 触发智能助手之后 清空消息，保证下次触发的时候不再发送上一次的消息
      smartMessages = []
      const obj = {
        url: 'ws://192.168.152.87:8765',
        sleepTime: 10,
        data: {
          task_description: [],
          process_id: data.processId
        }
      }
      console.log(obj)
      lastMessages.forEach((item) => {
        if (item.type === 'User' || item.type === 'Bot') {
          const key = item.type === 'User' ? 'Q' : 'A'
          const message = {}
          message[key] =
            item.type === 'User' ? item.message : item.answer || data.content
          obj.data.task_description.push(message)
        }
      })
      if (isWx()) {
        if (isAndroid()) {
          window.wanxiao_smart.executeBindMethod('run', JSON.stringify(obj))
        } else if (isIos()) {
          window.webkit.messageHandlers.openIntelligenceHelper.postMessage(
            JSON.stringify(obj)
          )
        }
      }
    } else if (data.type === 999) {
      answerObj.uuid = data.uuid
    }
    if (data.content && data.type !== 11) {
      answerObj.thinkFinished = true
      if (data.type == 5) {
        answerObj.answer = answerObj.answer + data.content
        answerObj.message = answerObj.answer
      } else {
        answerObj.answer = answerObj.answer + data.content
        answerObj.message = window.md
          .render(answerObj.answer)
          .replaceAll('&lt;br&gt;', '<br />')
      }
      // answerObj.answer =
      //   '俄罗斯和乌克兰冲突的最新进展是，俄罗斯表示愿意在不设先决条件下启动谈判，并提出五月停火倡议，但尚未得到乌克兰的回应<font color="grey" data-id="1">[1]</font><font color="grey" data-id="2">[2]</font>。乌克兰外长则表示，如果俄罗斯真的想要和平，就应该立即停火，而不是等到5月8日，同时乌克兰准备支持至少持续30天的持久、可信和彻底的停火。结论是，目前俄罗斯希望推动和谈进程，而乌克兰要求立即停火并持续至少30天，双方仍在就停火和谈判的具体条件进行沟通。'
      // answerObj.message = window.md
      //   .render(answerObj.answer)
      //   .replaceAll('&lt;br&gt;', '<br />')
      answerObj.isLoading = false
      scroll()
    }
  }
  const executeErrorMessage = (answerR) => {
    isAnswering.value = false
    isPending.value = false
    answerR.isTextEnd = true
    controller.abort()
    answerR.isLoading = false

    let animationType = ''
    continueNoanswerTimes.value++
    answerR.isError = true
    switch (continueNoanswerTimes.value) {
      case 1:
        answerR.message = config.apologyHint
        animationType = 'NoAnswer1'
        break
      case 2:
        if (config.apologyHintSecond) {
          answerR.message = config.apologyHintSecond
          animationType = 'NoAnswer2'
        } else {
          answerR.message = config.apologyHint
          animationType = 'NoAnswer1'
        }
        break
      case 3:
        if (config.apologyHintThree) {
          answerR.message = config.apologyHintThree
          animationType = 'NoAnswer3'
        } else {
          answerR.message = config.apologyHint
          animationType = 'NoAnswer1'
        }
        checkShowKefu()
        continueNoanswerTimes.value = 0
        break
    }
    playVoiceAndAnimate(animationType, answerR.message)
  }
  const resetProcess = () => {
    processObj.value.jtype = null
    processObj.value.link = ''
    processObj.value.appendToken = 0
  }
  const jumpByProcessID = () => {
    if (processObj.value.link) {
      if (processObj.value.jtype === 4) {
        if (!isMobile()) {
          proxy.$toast('请在移动端使用此功能')
          return
        }
        setTimeout(() => {
          window.location.href = processObj.value.link
        }, 1000)
      } else if (processObj.value.jtype === 2) {
        if (!isWeixinMini()) {
          proxy.$toast('请在微信小程序环境使用此功能')
          return
        }
        wx.miniProgram.navigateTo({
          url: processObj.value.link
        })
      } else if (processObj.value.jtype === 3) {
        const url =
          processObj.value.appendToken === 1
            ? addTokenToUrl(
                processObj.value.link,
                processObj.value.putTokenName,
                processObj.value.gainTokenName
              )
            : processObj.value.link
        setTimeout(() => {
          if (url === 'invalid url') {
            proxy.$toast('地址解析失败，请检查配置')
            return
          }
          jumpHttp(url)
        }, 1000)
      }
    }
  }

  // 停止生成
  const stopAi = () => {
    if (!isIos()) {
      if (Emit) {
        Emit('playVoice', '')
      }
      if (isAnswering.value) {
        playVoiceAndAnimate('Standby')
      }
    }
    if (controller) {
      controller.abort()
    }
  }

  // 修复ios scroll滚动失效bug
  const fixScroll = () => {
    if (chatBox.value.$el) {
      const scrollTop = chatBox.value.$el.scrollTop
      if (scrollTop <= 0 || scrollTop > chatBox.value.$el.offsetHeight) {
        document.body.style.overflow = 'hidden'
      } else {
        document.body.style.overflow = 'auto'
      }
    }
  }

  // 文档引用展示逻辑
  const showRefPop = ref(false)
  const refContent = ref('')
  const showRef = (e) => {
    showRefPop.value = true
    refContent.value = window.md.render(e)
    setTimeout(() => {
      document.getElementById('refpopInfo').scrollTop = 0
    })
  }

  // 图片预览
  const showImgPreview = (e) => {
    ImagePreview({
      images: e.imgs,
      startPosition: e.index
    })
  }

  // 点赞、点踩弹窗
  const feedType = ref('')
  const evaluteValue = ref('')
  const showEvalutePop = ref(false)
  const evaluteObj = ref()
  const showEvalute = (e) => {
    if (e.status === '1') {
      newEvaluate(
        {
          question: e.ask,
          ask: e.question,
          content: '',
          status: '1',
          feedType: '',
          chatType: e.chatType,
          uuid: e.uuid, // 唯一标识
          sessionId: sessionId.value || config.sessionId
        },
        true
      )
        .then(() => {
          messages.value[e.index].opsStatus = '1'
        })
        .catch((err) => {
          console.log(err)
        })
    } else {
      feedType.value = defaultFeedType.value
      showEvalutePop.value = true
      evaluteObj.value = e
    }
  }
  const evalute = () => {
    if (!feedType.value) {
      proxy.$toast('请选择问题类型')
      return
    }
    if (!evaluteValue.value) {
      proxy.$toast('请填写详细问题描述')
      return
    }
    newEvaluate(
      {
        question: evaluteObj.value.ask,
        ask: evaluteObj.value.question,
        content: evaluteValue.value,
        status: '2',
        chatType: evaluteObj.value.chatType,
        feedType: feedType.value,
        uuid: evaluteObj.value.uuid, // 唯一标识
        sessionId: sessionId.value || config.sessionId
      },
      true
    )
      .then(() => {
        messages.value[evaluteObj.value.index].opsStatus = '2'
        evaluteValue.value = ''
        showEvalutePop.value = false
      })
      .catch((err) => {
        console.log(err)
      })
  }
  const changeOpsStatus = (e) => {
    messages.value[evaluteObj.value.index].opsStatus = e
  }

  return {
    isZDWX,
    docObj,
    chatBox,
    messages,
    isPending,
    isAnswering,
    jumpByProcessID,
    processObj,
    send,
    sendInput,
    scroll,
    fixScroll,
    testTransportStatus,
    checkShowKefu,
    showRef,
    showRefPop,
    evaluteValue,
    showEvalute,
    showEvalutePop,
    feedType,
    evalute,
    changeOpsStatus,
    refContent,
    showImgPreview,
    stopAi,
    pushAgent,
    autoScroll
  }
}
